<?php
namespace App\Wen\Utils;
use App\Lib\Classes\AcAutomation;
use App\Lib\WeApp\WeApp;
use App\Models\User\WxUser;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use GuzzleHttp\Client;

class BaiduUtils{

    protected static $stop_words = ['互裸', '六合彩', '内射'];

    public static function get_baidu_access_token( $client_id, $client_secret ){
        if(_empty_($client_id) || _empty_($client_secret)){
            return null;
        }
        if(Cache::has('api:baidu:access_token:'.md5($client_id.$client_secret))){
            return Cache::get( 'api:baidu:access_token:'.md5($client_id.$client_secret) );
        }
        $accessTokenUrl='https://aip.baidubce.com/oauth/2.0/token';
        $request_data=array(
            'grant_type' => 'client_credentials',
            'client_id' => $client_id,
            'client_secret' => $client_secret,
        );
        $response = Http::asForm()->post($accessTokenUrl, $request_data);
        if($response->successful()){
            $obj = $response->json();
            if(_array_key($obj, 'error', '')){
                _logger_(__file__, __line__, $obj);
                return null;
            }
            Cache::forget('api:baidu:'.md5($client_id.$client_secret));
            Cache::put('api:baidu:'.md5($client_id.$client_secret), $obj['access_token'], $obj['expires_in'] - 1000);
            return $obj['access_token'];
        }
        return null;
    }

    /*
     * [
        'hit_level' => 0/1/2,
        'msg' => '不合规',
        'tip_list' => [],
        'hit_word' => []
        ]
     */

    public static function mp_text_filter($content){
        // 这里再次对合规的文本做微信的检测
        global $__MINI_GLOBAL_DEVICE__,$__MINI_GLOBAL_CURRENT_USER_ID__,$__MINI_GLOBAL_CURRENT_PLAYER_ID__;
        $ak = (new WeApp())->getAccessToken();
        if($ak){
            $client = new Client();
            $post = $client->post("https://api.weixin.qq.com/wxa/msg_sec_check?access_token={$ak}", [
                'body' =>json_encode( [
                    'openid' => WxUser::where('id', $__MINI_GLOBAL_CURRENT_PLAYER_ID__ > 0 ? $__MINI_GLOBAL_CURRENT_PLAYER_ID__ : $__MINI_GLOBAL_CURRENT_USER_ID__)->value('weixin_openid'),
                    'content' => $content,
                    'version' => 2,
                    'scene' => 1,
                ],JSON_UNESCAPED_UNICODE)] );
            $res = json_decode($post->getBody(), true);
            if($res){
                if($res['errcode'] === 0){
                    if($res['result']['suggest'] == 'pass'){
                        return [
                            'hit_level' => 0,
                            'msg' => '合规'
                        ];
                    }else{
                        $errcode_arr = [
                            100 => '正常',
                            10001 => '广告',
                            20001 => '时政',
                            20002 => '色情',
                            20003 => '辱骂',
                            20006 => '违法犯罪',
                            20008 => '欺诈',
                            20012 => '低俗',
                            20013 => '版权',
                            21000 => '其他'
                        ];
                        if($res['result']['suggest'] == 'risky'){
                            return [
                                'hit_level' => 2,
                                'msg' => '违规内容归属为',
                                'tip_list' => [
                                    _array_key($errcode_arr, $res['result']['label'], 'xx'),
                                ],
                                'hit_word' => [
                                    _array_key($errcode_arr, $res['result']['label'], 'xx'),
                                ]
                            ];
                        }else if($res['result']['suggest'] == 'review'){
                            return [
                                'hit_level' => 2,
                                'msg' => '内容违规',
                                'tip_list' => [

                                ],
                                'hit_word' => [

                                ]
                            ];
                        }
                    }
                }else{
                    return [
                        'hit_level' => 0,
                        'msg' => '合规'
                    ];
                }
            }
        }
        return [
            'hit_level' => 0,
            'msg' => '合规'
        ];
    }

    public static function stop_words_filter($content){
        $ac = new AcAutomation(self::$stop_words);
        $res = $ac->search($content);
        if(!_empty_($res)){
            $r = [
                'hit_level' => 2,
                'msg' => '存在禁用词',
                'tip_list' => [
                    '存在禁用词'
                ],
                'hit_word' => []
            ];
            foreach ($res as $pos) {
                $r['hit_word'][] = mb_substr($content,$pos[0],$pos[1] - $pos[0],'UTF-8');
            }
            return $r;
        }else{
            return [
                'hit_level' => 0,
                'msg' => '合规'
            ];
        }

    }

    public static function text_filter($content){

        if(_empty_($content)){
            return null;
        }
        global $__MINI_GLOBAL_CURRENT_USER_ID__;
        global $__MINI_GLOBAL_PAYCODE_4__;
        if(!$__MINI_GLOBAL_PAYCODE_4__){
            return [
                'hit_level' => -1,
                'msg' => 'you are not unlocked this',
                'tip_list' => [],
                'hit_word' => []
            ];
        }

        $stop_res = self::stop_words_filter($content);
        if($stop_res['hit_level'] == 2){
            return $stop_res;
        }

        $mp_res = self::mp_text_filter($content);
        if($mp_res['hit_level'] == 2){
            return $mp_res;
        }
        try {
            $access_token = self::get_baidu_access_token( Settings::get('app_baidu_filter_api_key'),Settings::get('app_baidu_filter_secret_key') );

            if($access_token){
                $textCensorUserDefinedUrl='https://aip.baidubce.com/rest/2.0/solution/v1/text_censor/v2/user_defined';

                $res = Http::asForm()->post($textCensorUserDefinedUrl."?access_token=".$access_token, ['text'=>$content, 'strategyId'=>(int)(Settings::get('app_baidu_filter_strategy_id', 1))]);

                if($res->successful()){
                    $res_obj = $res->json();
                    if(_array_key($res_obj, 'error_code',  0) > 0){
                        _logger_(__file__, __line__, $res_obj);
                        return self::mp_text_filter($content);
                    }
                    if(_array_key($res_obj, 'conclusionType', '') == 4){
                        // 审核失败
                        return self::mp_text_filter($content);
                    }else if(_array_key($res_obj, 'conclusionType', '') == 1){
                        return self::mp_text_filter($content);
                    }else if(_array_key($res_obj, 'conclusionType', '') == 2 || _array_key($res_obj, 'conclusionType', '') == 3){
                        $result = [
                            'hit_level' => 1,
                            'msg' => '疑似',
                            'tip_list' => [],
                            'hit_word' => []
                        ];
                        if(_array_key($res_obj, 'data', [])){
                            foreach ($res_obj['data'] as $detail){
                                if( _array_key($detail, 'msg', '')){
                                    if(strpos( $detail['msg'], '违禁词') !== false){
                                        $result['tip_list'][] = '存在违禁词';
                                    }else{
                                        $result['tip_list'][] = $detail['msg'];
                                    }
                                }

                                if(_array_key($detail, 'hits', [])){
                                    foreach (_array_key($detail, 'hits', []) as $hit){
                                        if(_array_key($hit, 'probability', 0.8) > 0.62){

                                            if( _array_key($hit, 'words', []) ){
                                                if(is_array($hit['words'])){
                                                    foreach ($hit['words'] as $words){
                                                        $result['hit_word'][] = $words;
                                                    }
                                                }else{
                                                    $result['hit_word'][] = $hit['words'];
                                                }
                                            }else if( _array_key($hit, 'details', []) ){
                                                foreach (_array_key($hit, 'details', []) as $word){
                                                    $result['hit_word'][] = $word;
                                                }
                                            }else if(_array_key($hit, 'modelHitPositions', [])){
                                                foreach (_array_key($hit, 'modelHitPositions', []) as $position){
                                                    if(is_array($position) && count($position) == 3){
                                                        if($position[2] >= 0.7){
                                                            $result['hit_word'][] = mb_substr($content, $position[0], $position[1] - $position[0] + 1);
                                                        }
                                                    }
                                                }
                                            }

                                        }
                                    }
                                }

                                if(_empty_($result['hit_word'])){
                                    if(_array_key($detail, 'details', [])){
                                        foreach (_array_key($detail, 'details', []) as $word){
                                            $result['hit_word'][] = $word;
                                        }
                                    }
                                }
                            }
                        }
                        if(_empty_($result['hit_word'])){
                            // 合规
                            return self::mp_text_filter($content);
                        }else{
                            if(count($result['hit_word']) >= 1){
                                $result['hit_level'] = 2;
                                $result['msg'] = '违规';
                            }
                        }
                        return $result;
                    }
                }
            }
            return null;
        }catch (\Exception $e){
            _logger_(__file__, __line__, $e->getMessage().'该问题产生于百度审核，疑似百度文本审核服务未开启，或已到期，或已用完');
            return [
                'hit_level' => 0,
                'msg' => '合规'
            ];
        }
    }

}
